package com.yuyou.fn.crm.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.yuyou.fn.common.lang.Tuple2;
import com.yuyou.fn.common.service.ISmsService;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.Threads;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.crm.entity.CustomerResource;
import com.yuyou.fn.crm.entity.VisitMonitor;
import com.yuyou.fn.crm.entity.WorkSetupOfCampus;
import com.yuyou.fn.crm.entity.WorkSetupTemplate;
import com.yuyou.fn.crm.mapper.VisitMonitorMapper;
import com.yuyou.fn.crm.service.ICustomerResourceService;
import com.yuyou.fn.crm.service.IVisitMonitorService;
import com.yuyou.fn.crm.service.IWorkSetupOfCampusService;
import com.yuyou.fn.crm.service.IWorkSetupTemplateService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 * VisitMonitor 表数据服务层接口实现类
 *
 */
@Service
public class VisitMonitorServiceImpl extends SuperServiceImpl<VisitMonitorMapper, VisitMonitor,Long> implements IVisitMonitorService {

    private final Logger log = LoggerFactory.getLogger(VisitMonitorServiceImpl.class);

    private final Map<Integer,String> priorityMap = Tuple2.asMap(Tuple2.of(0,"low") , Tuple2.of(1,"mid"),Tuple2.of(2,"high")) ;

    @Resource
    private ICustomerResourceService customerResourceService;

    @Resource
    private IWorkSetupOfCampusService workSetupOfCampusService;

    @Resource
    private IWorkSetupTemplateService workSetupTemplateService;

    @Resource
    private ISmsService smsService;


    @Override
    public void createVisitMonitor(List<CustomerResource> customerResources) {


        List<Long> campusIds = BeanUtils.toList(customerResources,"campusId");

        List<WorkSetupOfCampus> workSetupOfCampuses = workSetupOfCampusService.findWorkSetupOfCampusOfOpen(campusIds);
        List<Long> workSetupTemplateIds =  BeanUtils.toList(workSetupOfCampuses,"workSetupTemplateId") ;
        List<WorkSetupTemplate> workSetupTemplates = workSetupTemplateService.findByIds(workSetupTemplateIds);
        Map<Long,WorkSetupOfCampus> campusId2WorkSetupOfCampus =  BeanUtils.toMap(workSetupOfCampuses,"campusId");
        Map<Long,WorkSetupTemplate> workSetupTemplateId2WorkSetupTemplate = BeanUtils.toMap(workSetupTemplates,"workSetupTemplateId") ;

        for(CustomerResource customerResource : customerResources ){
            WorkSetupOfCampus workSetupOfCampus = campusId2WorkSetupOfCampus.get(customerResource.getCampusId());
            if(workSetupOfCampus ==null || workSetupOfCampus.getStatus() != 1 ){
                continue;
            }
            WorkSetupTemplate workSetupTemplate = workSetupTemplateId2WorkSetupTemplate.get(workSetupOfCampus.getWorkSetupTemplateId());

            JSONObject remindConfigOfCampus =  JSONObject.parseObject(workSetupOfCampus.getRemindConfig());
            JSONObject remindConfig =  JSONObject.parseObject(workSetupTemplate.getRemindConfig());

            JSONArray phoneConfigs = remindConfigOfCampus.getJSONArray(priorityMap.get(customerResource.getPriority()));
            JSONArray remindTimeConfigs = remindConfig.getJSONArray(priorityMap.get(customerResource.getPriority()));
            if(phoneConfigs != null ){
                for(int i = 0 ; i < phoneConfigs.size() ;i++ ){
                    JSONObject phoneConfig = phoneConfigs.getJSONObject(i);
                    String jobName  = phoneConfig.getString("jobName" );
                    int findIndex  = - 1 ;
                    for(int ii = 0 ; ii < remindTimeConfigs.size() ;ii++ ){
                        JSONObject rtimeConfig = remindTimeConfigs.getJSONObject(ii);
                        if(jobName.equals( rtimeConfig.getString("jobName") )){
                            findIndex = ii ;
                        }
                    }

                    if(findIndex == -1 ){
                        continue;
                    }

                    String phone  =phoneConfig.getString("phone");
                    String name  = phoneConfig.getString("name") ;

                    if(phone == null || name == null ){
                        continue;
                    }

                    Date now = customerResource.getAlloCreateTime();

                    Date notifyTime  = calNotifyTime( now , remindTimeConfigs.getJSONObject(findIndex), JSONObject.parseObject( workSetupTemplate.getTimeConfig() ) , workSetupTemplate.getExcludeDates() );

                    if( notifyTime == null  ){
                        continue;
                    }

                    VisitMonitor visitMonitor = new VisitMonitor();
                    visitMonitor.setCustomerResourceId(customerResource.getCustomerResourceId());
                    visitMonitor.setMonitorStatus(0);
                    visitMonitor.setAlertStatus(0);
                    visitMonitor.setNotifyPhone(phone);
                    visitMonitor.setNotifyWho(name);
                    visitMonitor.setNotifyTime(notifyTime);
                    visitMonitor.setCreateTime(now);
                    visitMonitor.setUpdateTime(now);
                    insertSelective(visitMonitor);
                }
            }
        }
    }

    @Override
    @Transactional
    public void monitorScan() {

        Example<VisitMonitor> example = VisitMonitor.createExample();
        example.createCriteria().andEqualTo("monitorStatus" ,0 ).andLessThan("notifyTime",TimeUtils.now() );

        List<VisitMonitor> monitors = findListByExample(example);
        for(VisitMonitor visitMonitor : monitors ){

            CustomerResource customerResource = customerResourceService.findById(visitMonitor.getCustomerResourceId());
            VisitMonitor update = new VisitMonitor();
            update.setVisitMonitorId(visitMonitor.getVisitMonitorId());
            update.setMonitorStatus(1);
            if(customerResource.getVisitStatus() == 0 ){
                update.setAlertStatus(1);
                Threads.dispatch(() -> {
                    try {
                        smsService.send(Arrays.asList(visitMonitor.getNotifyPhone()), String.format("您好，%s尚有超时未回访的名单，请知悉并督促跟进，谢谢",customerResource.getCampusName() )  );
                    } catch (Exception e) {
                        log.error("Send sms fail",e );
                    }
                });
            }
            updateSelectiveById(update);

            CustomerResource customerResourceUpdate=new CustomerResource();
            customerResourceUpdate.setCustomerResourceId(customerResource.getCustomerResourceId());
            customerResourceUpdate.setUpdateTime(TimeUtils.now());
            customerResourceUpdate.setTimeoutStatus(1);
            customerResourceService.updateSelectiveById(customerResourceUpdate);

        }


    }


    @Override
    public List<VisitMonitor> findVisitMonitorByCustomerResourceIds(List<Long> customerResourceIds) {
        Example<VisitMonitor> example = VisitMonitor.createExample();
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("customerResourceId" ,customerResourceIds );

        List<VisitMonitor> list = findListByExample(example);

        if(list == null ){
            return Collections.EMPTY_LIST ;
        }

        return list ;
    }

    private Date calNotifyTime(Date now, JSONObject remindConfig , JSONObject timeConfig , String excludesDates ) {

        Integer time  = remindConfig.getInteger("time");

        if(time == null || timeConfig.isEmpty() ){
            return null ;
        }

        Map<String,Tuple2<String,String>> times = new HashMap<>();
        for(String weekDate  : timeConfig.keySet() ){

            String am = timeConfig.getJSONObject(weekDate).getString("am");
            String pm = timeConfig.getJSONObject(weekDate).getString("pm");

            if( am != null && am.length() == 11 ){
                String[] splits = am.split("-");
                if(splits.length != 2  ){
                    continue;
                }
                times.put( weekDate + "上午", Tuple2.of(splits[0],splits[1]));
            }

            if( pm != null && pm.length() == 11 ){
                String[] splits = pm.split("-");
                if(splits.length != 2  ){
                    continue;
                }
                times.put( weekDate + "下午" , Tuple2.of(splits[0],splits[1]));
            }

        }

        if(times.isEmpty()){
            return null ;
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm Ea",Locale.CHINA );

        while (time > 0 ){
            now  = DateUtils.addMinutes(now, 1 );
            String[] dates = dateFormat.format(now).split(" ");
            if(StringUtils.isNoneEmpty(excludesDates)){
                if(excludesDates.contains(dates[0])){
                    now  =TimeUtils.endOfDate(now);
                    continue;
                }
            }

            Tuple2<String, String> timeSeg = times.get(dates[2]);
            if (timeSeg==null){
                now= TimeUtils.endOfDate(now);
                continue;
            }
            if( timeSeg != null && (dates[1].compareTo(timeSeg.getFirst()) <= 0 || dates[1].compareTo(timeSeg.getSecond()) > 0 ) ){
                continue;
            }
            time-- ;
        }
        return now;
    }


    @Override
    public void deleteByCustomerResourceIds(List<Long> customerResourceIds) {
        if (!customerResourceIds.isEmpty()){
            Example<VisitMonitor> example=VisitMonitor.createExample();
            example.createCriteria().andIn("customerResourceId",customerResourceIds);
            this.deleteByExample(example);
        }
    }
}